package dev.ece.util.obj;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;

public class ValueUtils {

	public static Object get(Object obj, String name) {
		String[] names = StringUtils.split(name, ".");
		if(names.length > 1) {
			Object object = obj;
			for(int i=0; i<names.length; i++) {
				object = simpleGet(object, names[i]);
			}
			return object;
		} else {
			return simpleGet(obj, names[0]);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static Object simpleGet(Object obj, String name) {
		Object value = null;
		try {
			value = MethodUtils.invokeMethod(obj, getter(name));
		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
			if(obj instanceof Map) {
				value = ((Map<String, Object>) obj).get(name);
			}
		} 
		return value;
	}
	
	public static String getter(String name) {
		String firstUpcaseChar = StringUtils.upperCase(StringUtils.left(name, 1));
		return StringUtils.join("get", firstUpcaseChar, StringUtils.substring(name, 1));
	}
	
	public static void set(Object obj, String name, Object value) {
		String[] names = StringUtils.split(name, ".");
		if(names.length > 1) {
			Object object = obj;
			int lastIndex = names.length - 1;
			for(int i=0; i<lastIndex; i++) {
				object = simpleGet(object, names[i]);
			}
			simpleSet(object, names[lastIndex], value);
		} else {
			simpleSet(obj, names[0], value);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void simpleSet(Object obj, String name, Object value) {
		try {
			MethodUtils.invokeMethod(obj, setter(name), value);
		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
			if(obj instanceof Map) {
				((Map<String, Object>) obj).put(name, value);
			}
		}
	}
	
	public static String setter(String name) {
		String firstUpcaseChar = StringUtils.upperCase(StringUtils.left(name, 1));
		return StringUtils.join("set", firstUpcaseChar, StringUtils.substring(name, 1));
	}
	
}
